import System
from System.IO import StreamReader
from System.Net import HttpWebRequest, NetworkCredential, WebException

import clr
clr.AddReference('System.Web')

import datetime
import Program
import mySecsHelper

class googleHelper:
    "Helper methods to connect to google appspot"
    def __init__(self, host="mysecs.appspot.com", email = None, password = None, appName = "mySecsWndClient"):
        """
        Creates a new connection to mysecs hosting in GAE
        Args:
            host: Host to which send the request (by default it is mysecs.appspot.com)
            email: email id to validate
            password: google account password
        """
        Program.mysecs10.mysecsLog.Log("initializing googleHelper")
        self.Host = host
        self.UserName = email
        self.Password = password        
        #initial setup
        self.auth_uri = 'https://www.google.com/accounts/ClientLogin'
        self.Cookies = System.Net.CookieContainer()
        self.Proxy = System.Net.WebProxy.GetDefaultProxy()
        self.IsAuthenticated = False
        self.AppName = appName        
        Program.mysecs10.mysecsLog.Log("finished initialization")
        
    def Authenticate(self):
        """Authenticate via Google Accounts and then login into the server"""
        Program.mysecs10.mysecsLog.Log("in authenticate: uname:%s pwd:%s" % (self.UserName, self.Password))
        self.IsAuthenticated = False
        
        if self.UserName is None or self.Password is None:
            return
            
        req = HttpWebRequest.Create(self.auth_uri)
        #setup proxy to default one (of IE)
        self.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials
        req.Proxy = self.Proxy
        
        req.CookieContainer = self.Cookies
        req.UserAgent = self.AppName
        req.Method = "POST"
        
        client_login_data= "Email=%s&Passwd=%s&service=ah&source=%s&accountType=HOSTED_OR_GOOGLE" % \
                           (System.Web.HttpUtility.UrlEncode(self.UserName), \
                            System.Web.HttpUtility.UrlEncode(self.Password), \
                            System.Web.HttpUtility.UrlEncode(self.AppName))
        
        #http://www.25hoursaday.com/weblog/2007/12/31/CommandLineClientForGoogleReaderInIronPython.aspx
        req.ContentLength = client_login_data.Length
        req.ContentType = 'application/x-www-form-urlencoded'
        send_data = System.Text.Encoding.ASCII.GetBytes(client_login_data)
        reqStream = req.GetRequestStream()
        reqStream.Write(send_data,0,send_data.Length)
        reqStream.Close()
                
        rsp = req.GetResponse()
        response = StreamReader(rsp.GetResponseStream()).ReadToEnd()        
        rsp.Close()
        
        #We are interested only in auth token
        auth_resp_dict = dict(x.split("=")
                      for x in response.split("\n") if x)
        authtoken = auth_resp_dict["Auth"]
        
        Program.mysecs10.mysecsLog.Log("authtoken is:%s" % authtoken)        
        
        #login into the server with the authtoken
        full_serv_uri = "http://%s/_ah/login?auth=%s" % (self.Host, System.Web.HttpUtility.UrlEncode(authtoken))
        req = HttpWebRequest.Create(full_serv_uri)
        req.Proxy = self.Proxy
        req.UserAgent = self.AppName
        req.Method = "GET"
        req.CookieContainer = self.Cookies
        
        try:
            rsp = req.GetResponse()
            resp_body = StreamReader(rsp.GetResponseStream()).ReadToEnd()
            rsp.Close()
            self.IsAuthenticated = True
            Program.mysecs10.mysecsLog.Log("Auth response:%s" % resp_body)
        except System.Net.WebException, ex:
                Program.mysecs10.mysecsLog.Log("There is error while authenticating; code: %s, message:%s" %(ex.Status, ex.Response))        
        
    def BuildData(self):
        """Get records that need to be udpated"""
        Program.mysecs10.mysecsLog.Log("in builddata")
        dbconn= mySecsHelper.get_or_create_db()
        dbcmd = dbconn.CreateCommand()
        dbcmd.CommandText = "select fromtime,totime,timespent,appname,apptitle,ipaddress,domainname,osversion, timeid from time_details where Uploaded=0 and apptitle != ''"
        
        timedetails = dbcmd.ExecuteReader()        
        time_details = []
        while timedetails.Read():
            from_time   = timedetails[0]
            to_time     = timedetails[1]
            time_spent  = timedetails[2]
            app_name    = timedetails[3]
            app_title   = timedetails[4]
            ip_address   = timedetails[5]
            domain_name  = timedetails[6]
            os_version   = timedetails[7]
            time_id      = timedetails[8]
            source       = self.AppName
            time_details.append(dict(fromtime=from_time, totime=to_time, timespent=time_spent,task=app_name, taskinfo=app_title,ipaddress=ip_address,domainname=domain_name, osversion=os_version, source=source, timeid=time_id))
        dbconn.Close()
        
        return time_details
        
    def PostData(self, sender, event):
        """Post to server; called from timer event; timer event passes sender and event"""
        Program.mysecs10.mysecsLog.Log("in postdata; authentication:%s" % self.IsAuthenticated)
        time_details = self.BuildData()
        submit_data = "time_details=%s" % str(time_details)
        
        Program.mysecs10.mysecsLog.Log("submit_data:%s" % submit_data)
        Program.mysecs10.mysecsLog.Log("is on dev?:%s" % Program.mysecs10.IsOnDev)
        
        if not self.IsAuthenticated:
            if Program.mysecs10.IsOnDev == 1:
                self.IsAuthenticated = True
            else:
                self.Authenticate()

        if self.IsAuthenticated and len(time_details) > 0:                              
            Program.mysecs10.mysecsLog.Log("going to update")
            #note the last /
            req = HttpWebRequest.Create("http://%s/api/update/" % self.Host)
            req.UserAgent = self.AppName
            req.Method = "POST"
            
            req.ContentLength = submit_data.Length
            req.ContentType = 'application/x-www-form-urlencoded'
            req.CookieContainer = self.Cookies

            send_data = System.Text.Encoding.ASCII.GetBytes(submit_data)
            reqStream = req.GetRequestStream()
            reqStream.Write(send_data,0,send_data.Length)
            reqStream.Close()
            
            where_cond = '(' + ','.join(["%s" % time_snapshot['timeid'] for time_snapshot in time_details]) + ')'
            Program.mysecs10.mysecsLog.Log("condition is:%s" % where_cond)
            
            dbconn= mySecsHelper.get_or_create_db()
            dbcmd = dbconn.CreateCommand()
            dbcmd.CommandText = 'update time_details set uploaded=1 where timeid in ' + where_cond
            Program.mysecs10.mysecsLog.Log("update stmt is:%s" % dbcmd.CommandText)
            timedetails = dbcmd.ExecuteReader()
            dbconn.Close()
            
            try:
                rsp = req.GetResponse()
                update_response = StreamReader(rsp.GetResponseStream()).ReadToEnd()
                rsp.Close()                                
                    
                Program.mysecs10.mysecsLog.Log("response is:%s" % update_response)
            except System.Net.WebException, ex:
                Program.mysecs10.mysecsLog.Log("There is error while updating server; code:%s message:%s ; data:%s" %(ex.Status.ToString(), ex.Message, ex.Data))